﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.SqlTypes;
using System.Drawing;

namespace Noris.Tools.TraceVisualiser.Support
{
    // internal class for conversion string - object
	/// <summary>
	/// Knihovna statických konverzních metod mezi simple typy a stringem
	/// </summary>
	public static class Convertor
    {
        #region Sada krátkých metod pro serializaci a deserializaci Simple typů (jsou vyjmenované v TypeLibrary._SimpleTypePrepare())
        #region System types
        public static string BooleanToString(object value)
		{
			return ((Boolean)value ? "true" : "false");
		}
        public static string BooleanToString(object value, string textTrue, string textFalse)
        {
            return ((Boolean)value ? textTrue : textFalse);
        }
		public static object StringToBoolean(string text)
		{
            return (!String.IsNullOrEmpty(text) && (text.ToLower() == "true" || text == "1" || text.ToLower()  == "a" || text.ToLower()  == "y"));
		}
		public static string ByteToString(object value)
		{
			return ((Byte)value).ToString();
		}
		public static object StringToByte(string text)
		{
			if (String.IsNullOrEmpty(text)) return (Byte)0;
			Int32 value;
			if (!Int32.TryParse(text, System.Globalization.NumberStyles.Any, _Nmfi, out value)) return (Byte)0;
			Byte b = (Byte)(value & 0x00FF);
			return b;
		}
		public static string DateTimeToString(object value)
		{
			DateTime dateTime = (DateTime)value;
			if (dateTime.Millisecond == 0 && dateTime.Second == 0)
				return dateTime.ToString("D", _Dtfi);
			return dateTime.ToString("F", _Dtfi);
		}
		public static object StringToDateTime(string text)
		{
			if (String.IsNullOrEmpty(text)) return DateTime.MinValue;
			DateTime value;
			if (DateTime.TryParseExact(text, "D", _Dtfi, System.Globalization.DateTimeStyles.AllowWhiteSpaces | System.Globalization.DateTimeStyles.NoCurrentDateDefault, out value))
				return value;
			if (DateTime.TryParseExact(text, "F", _Dtfi, System.Globalization.DateTimeStyles.AllowWhiteSpaces | System.Globalization.DateTimeStyles.NoCurrentDateDefault, out value))
				return value;

			return DateTime.MinValue;
		}
		public static string DateTimeOffsetToString(object value)
		{
			DateTimeOffset dateTimeOffset = (DateTimeOffset)value;
			return dateTimeOffset.ToString("F", _Dtfi);
		}
		public static object StringToDateTimeOffset(string text)
		{
			if (String.IsNullOrEmpty(text)) return DateTimeOffset.MinValue;
			DateTimeOffset value;
			if (!DateTimeOffset.TryParseExact(text, "D", _Dtfi, System.Globalization.DateTimeStyles.AllowWhiteSpaces | System.Globalization.DateTimeStyles.NoCurrentDateDefault, out value)) return DateTimeOffset.MinValue;
			return value;
		}
		public static string DecimalToString(object value)
		{
			return ((Decimal)value).ToString("N", _Nmfi);
		}
		public static object StringToDecimal(string text)
		{
			if (String.IsNullOrEmpty(text)) return (Decimal)0;
			Decimal value;
			if (!Decimal.TryParse(text, System.Globalization.NumberStyles.Any, _Nmfi, out value)) return (Decimal)0;
			return value;
		}
		public static string DoubleToString(object value)
		{
			return ((Double)value).ToString("N", _Nmfi);
		}
		public static object StringToDouble(string text)
		{
			if (String.IsNullOrEmpty(text)) return (Double)0;
			Double value;
			if (!Double.TryParse(text, System.Globalization.NumberStyles.Any, _Nmfi, out value)) return (Double)0;
			return value;
		}
		public static string GuidToString(object value)
		{
			return ((Guid)value).ToString("N", _Nmfi);
		}
		public static object StringToGuid(string text)
		{
			if (String.IsNullOrEmpty(text)) return Guid.Empty;
			Guid value;
			if (!Guid.TryParse(text, out value)) return Guid.Empty;
			return value;
		}
		public static string CharToString(object value)
		{
			return ((Char)value).ToString();
		}
		public static object StringToChar(string text)
		{
			if (String.IsNullOrEmpty(text)) return Char.MinValue;
			Char value;
			if (!Char.TryParse(text, out value)) return Char.MinValue;
			return value;
		}
		public static string Int16ToString(object value)
		{
			return ((Int16)value).ToString();
		}
		public static object StringToInt16(string text)
		{
			if (String.IsNullOrEmpty(text)) return (Int16)0;
			Int16 value;
			if (!Int16.TryParse(text, System.Globalization.NumberStyles.Any, _Nmfi, out value)) return (Int16)0;
			return value;
		}
		public static string Int32ToString(object value)
		{
			return ((Int32)value).ToString();
		}
		public static object StringToInt32(string text)
		{
			if (String.IsNullOrEmpty(text)) return (Int32)0;
			Int32 value;
			if (!Int32.TryParse(text, System.Globalization.NumberStyles.Any, _Nmfi, out value)) return (Int32)0;
			return value;
		}
		public static string Int64ToString(object value)
		{
			return ((Int64)value).ToString();
		}
		public static object StringToInt64(string text)
		{
			if (String.IsNullOrEmpty(text)) return (Int64)0;
			Int64 value;
			if (!Int64.TryParse(text, System.Globalization.NumberStyles.Any, _Nmfi, out value)) return (Int64)0;
			return value;
		}
		public static string IntPtrToString(object value)
		{
			return ((IntPtr)value).ToInt64().ToString("G");
		}
		public static object StringToIntPtr(string text)
		{
			if (String.IsNullOrEmpty(text)) return (IntPtr)0;
			Int64 int64;
			if (!Int64.TryParse(text, System.Globalization.NumberStyles.Any, _Nmfi, out int64)) return (IntPtr)0;
			return new IntPtr(int64);
		}
		public static string SByteToString(object value)
		{
			return ((SByte)value).ToString();
		}
		public static object StringToSByte(string text)
		{
			if (String.IsNullOrEmpty(text)) return (SByte)0;
			SByte value;
			if (!SByte.TryParse(text, System.Globalization.NumberStyles.Any, _Nmfi, out value)) return (SByte)0;
			return value;
		}
		public static string SingleToString(object value)
		{
			return ((Single)value).ToString("N", _Nmfi);
		}
		public static object StringToSingle(string text)
		{
			if (String.IsNullOrEmpty(text)) return (Single)0;
			Single value;
			if (!Single.TryParse(text, System.Globalization.NumberStyles.Any, _Nmfi, out value)) return (Single)0;
			return value;
		}
		public static string StringToString(object value)
		{
			if (value == null) return null;
			return (string)value;
		}
		public static object StringToString(string text)
		{
			if (text == null) return null;
			return text;
		}
		public static string TimeSpanToString(object value)
		{
			return ((TimeSpan)value).ToString("N", _Dtfi);
		}
		public static object StringToTimeSpan(string text)
		{
			if (String.IsNullOrEmpty(text)) return TimeSpan.Zero;
			TimeSpan value;
			if (!TimeSpan.TryParse(text, _Dtfi, out value)) return TimeSpan.Zero;
			return value;
		}
		public static string UInt16ToString(object value)
		{
			return ((UInt16)value).ToString();
		}
		public static object StringToUInt16(string text)
		{
			if (String.IsNullOrEmpty(text)) return (UInt16)0;
			UInt16 value;
			if (!UInt16.TryParse(text, System.Globalization.NumberStyles.Any, _Nmfi, out value)) return (UInt16)0;
			return value;
		}
		public static string UInt32ToString(object value)
		{
			return ((UInt32)value).ToString();
		}
		public static object StringToUInt32(string text)
		{
			if (String.IsNullOrEmpty(text)) return (UInt32)0;
			UInt32 value;
			if (!UInt32.TryParse(text, System.Globalization.NumberStyles.Any, _Nmfi, out value)) return (UInt32)0;
			return value;
		}
		public static string UInt64ToString(object value)
		{
			return ((UInt64)value).ToString();
		}
		public static object StringToUInt64(string text)
		{
			if (String.IsNullOrEmpty(text)) return (UInt64)0;
			UInt64 value;
			if (!UInt64.TryParse(text, System.Globalization.NumberStyles.Any, _Nmfi, out value)) return (UInt64)0;
			return value;
		}
		public static string UIntPtrToString(object value)
		{
			return ((UIntPtr)value).ToUInt64().ToString("G");
		}
		public static object StringToUIntPtr(string text)
		{
			if (String.IsNullOrEmpty(text)) return (UIntPtr)0;
			UInt64 uint64;
			if (!UInt64.TryParse(text, System.Globalization.NumberStyles.Any, _Nmfi, out uint64)) return (UIntPtr)0;
			return new UIntPtr(uint64);
		}
        #endregion
        #region Nullable types
        public static string Int32NToString(object value)
        {
            Int32? v = (Int32?)value;
            return (v.HasValue ? v.Value.ToString() : "null");
        }
        public static object StringToInt32N(string text)
        {
            if (String.IsNullOrEmpty(text)) return (Int32?)null;
            if (text.ToLower().Trim() == "null") return (Int32?)null;
            Int32 value;
            if (!Int32.TryParse(text, System.Globalization.NumberStyles.Any, _Nmfi, out value)) return (Int32?)null;
            return (Int32?)value;
        }
        #endregion
        #region Sql Types
        public static string SqlBinaryToString(object value)
		{
			if (value == null) return null;
			SqlBinary data = (SqlBinary)value;
			if (data.IsNull) return null;
			return Convert.ToBase64String(data.Value);
		}
		public static object StringToSqlBinary(string text)
		{
			if (String.IsNullOrEmpty(text)) return SqlBinary.Null;
			return new SqlBinary(Convert.FromBase64String(text));
		}
		public static string SqlBooleanToString(object value)
		{
			if (value == null) return null;
			SqlBoolean data = (SqlBoolean)value;
			if (data.IsNull) return null;
			return (data.Value ? "true" : "false");
		}
		public static object StringToSqlBoolean(string text)
		{
			if (String.IsNullOrEmpty(text)) return SqlBoolean.Null;
			string data = text.Trim().ToLower();
			return (text == "true" ? SqlBoolean.True :
				   (text == "false" ? SqlBoolean.False : SqlBoolean.Null));
		}
		public static string SqlByteToString(object value)
		{
			if (value == null) return null;
			SqlByte data = (SqlByte)value;
			if (data.IsNull) return null;
			return data.Value.ToString();
		}
		public static object StringToSqlByte(string text)
		{
			if (String.IsNullOrEmpty(text)) return SqlByte.Null;
			Int32 value;
			if (!Int32.TryParse(text, System.Globalization.NumberStyles.Any, _Nmfi, out value)) return SqlByte.Null;
			SqlByte b = new SqlByte((Byte)(value & 0x00FF));
			return b;
		}
		public static string SqlDateTimeToString(object value)
		{
			if (value == null) return null;
			SqlDateTime data = (SqlDateTime)value;
			if (data.IsNull) return null;
			return data.Value.ToString("F", _Dtfi);
		}
		public static object StringToSqlDateTime(string text)
		{
			if (String.IsNullOrEmpty(text)) return SqlDateTime.Null;
			DateTime value;
			if (!DateTime.TryParseExact(text, "D", _Dtfi, System.Globalization.DateTimeStyles.AllowWhiteSpaces | System.Globalization.DateTimeStyles.NoCurrentDateDefault, out value)) return SqlDateTime.Null;
			return new SqlDateTime(value);
		}
		public static string SqlDecimalToString(object value)
		{
			if (value == null) return null;
			SqlDecimal data = (SqlDecimal)value;
			if (data.IsNull) return null;
			return data.Value.ToString("N", _Nmfi);
		}
		public static object StringToSqlDecimal(string text)
		{
			if (String.IsNullOrEmpty(text)) return SqlDecimal.Null;
			Decimal value;
			if (!Decimal.TryParse(text, System.Globalization.NumberStyles.Any, _Nmfi, out value)) return SqlDecimal.Null;
			return new SqlDecimal(value);
		}
		public static string SqlDoubleToString(object value)
		{
			if (value == null) return null;
			SqlDouble data = (SqlDouble)value;
			if (data.IsNull) return null;
			return data.Value.ToString("N", _Nmfi);
		}
		public static object StringToSqlDouble(string text)
		{
			if (String.IsNullOrEmpty(text)) return SqlDouble.Null;
			Double value;
			if (!Double.TryParse(text, System.Globalization.NumberStyles.Any, _Nmfi, out value)) return SqlDouble.Null;
			return new SqlDouble(value);
		}
		public static string SqlGuidToString(object value)
		{
			if (value == null) return null;
			SqlGuid data = (SqlGuid)value;
			if (data.IsNull) return null;
			return data.Value.ToString("N", _Nmfi);
		}
		public static object StringToSqlGuid(string text)
		{
			if (String.IsNullOrEmpty(text)) return SqlGuid.Null;
			Guid value;
			if (!Guid.TryParse(text, out value)) return SqlGuid.Null;
			return new SqlGuid(value);
		}
		public static string SqlInt16ToString(object value)
		{
			if (value == null) return null;
			SqlInt16 data = (SqlInt16)value;
			if (data.IsNull) return null;
			return data.Value.ToString();
		}
		public static object StringToSqlInt16(string text)
		{
			if (String.IsNullOrEmpty(text)) return SqlInt16.Null;
			Int16 value;
			if (!Int16.TryParse(text, System.Globalization.NumberStyles.Any, _Nmfi, out value)) return SqlInt16.Null;
			return new SqlInt16(value);
		}
		public static string SqlInt32ToString(object value)
		{
			if (value == null) return null;
			SqlInt32 data = (SqlInt32)value;
			if (data.IsNull) return null;
			return data.Value.ToString();
		}
		public static object StringToSqlInt32(string text)
		{
			if (String.IsNullOrEmpty(text)) return SqlInt32.Null;
			Int32 value;
			if (!Int32.TryParse(text, System.Globalization.NumberStyles.Any, _Nmfi, out value)) return SqlInt32.Null;
			return new SqlInt32(value);
		}
		public static string SqlInt64ToString(object value)
		{
			if (value == null) return null;
			SqlInt64 data = (SqlInt64)value;
			if (data.IsNull) return null;
			return data.Value.ToString();
		}
		public static object StringToSqlInt64(string text)
		{
			if (String.IsNullOrEmpty(text)) return SqlInt64.Null;
			Int64 value;
			if (!Int64.TryParse(text, System.Globalization.NumberStyles.Any, _Nmfi, out value)) return SqlInt64.Null;
			return new SqlInt64(value);
		}
		public static string SqlMoneyToString(object value)
		{
			if (value == null) return null;
			SqlMoney data = (SqlMoney)value;
			if (data.IsNull) return null;
			return data.Value.ToString();
		}
		public static object StringToSqlMoney(string text)
		{
			if (String.IsNullOrEmpty(text)) return SqlMoney.Null;
			Decimal value;
			if (!Decimal.TryParse(text, System.Globalization.NumberStyles.Any, _Nmfi, out value)) return SqlMoney.Null;
			return new SqlMoney(value);
		}
		public static string SqlSingleToString(object value)
		{
			if (value == null) return null;
			SqlSingle data = (SqlSingle)value;
			if (data.IsNull) return null;
			return data.Value.ToString();
		}
		public static object StringToSqlSingle(string text)
		{
			if (String.IsNullOrEmpty(text)) return SqlSingle.Null;
			Single value;
			if (!Single.TryParse(text, System.Globalization.NumberStyles.Any, _Nmfi, out value)) return SqlSingle.Null;
			return new SqlSingle(value);
		}
		public static string SqlStringToString(object value)
		{
			if (value == null) return null;
			SqlString data = (SqlString)value;
			if (data.IsNull) return null;
			return data.Value;
		}
		public static object StringToSqlString(string text)
		{
			if (String.IsNullOrEmpty(text)) return SqlString.Null;
			return text;
		}
        #endregion
        #region Drawing Types
        public static string ColorToString(object value)
        {
            if (value is KnownColor)
            {
                KnownColor knownColor = (KnownColor)value;
                return System.Enum.GetName(typeof(KnownColor), knownColor);
            }
            if (!(value is Color))
                return "";
            Color data = (Color)value;
            if (data.IsKnownColor)
                return System.Enum.GetName(typeof(KnownColor), data.ToKnownColor());
            if (data.IsNamedColor)
                return data.Name;
            if (data.IsSystemColor)
                return "System." + data.ToString();
            if (data.A < 255)
                return ("#" + data.A.ToString("X2") + data.R.ToString("X2") + data.G.ToString("X2") + data.B.ToString("X2")).ToUpper();
            return ("#" + data.R.ToString("X2") + data.G.ToString("X2") + data.B.ToString("X2")).ToUpper();
        }
        public static object StringToColor(string text)
        {
            if (String.IsNullOrEmpty(text)) return Color.Empty;
            string t = text.Trim();                      // Jméno "Orchid", nebo hexa #806040 (RGB), nebo hexa "#FF808040" (ARGB).
            if (t.Length == 7 && t[0] == '#' && ContainOnlyHexadecimals(t.Substring(1, 6)))
                return StringRgbToColor(t);
            if (t.Length == 9 && t[0] == '#' && ContainOnlyHexadecimals(t.Substring(1, 8)))
                return StringARgbToColor(t);
            return StringNameToColor(t);
        }
        private static object StringNameToColor(string name)
        {
            KnownColor known;
            if (System.Enum.TryParse<KnownColor>(name, out known))
                return Color.FromKnownColor(known);

            try
            {
                return Color.FromName(name);
            }
            catch
            { }
            return Color.Empty;
        }
        private static object StringARgbToColor(string t)
        {
            int a = HexadecimalToInt32(t.Substring(1, 2));
            int r = HexadecimalToInt32(t.Substring(3, 2));
            int g = HexadecimalToInt32(t.Substring(5, 2));
            int b = HexadecimalToInt32(t.Substring(7, 2));
            return Color.FromArgb(a, r, g, b);
        }
        private static object StringRgbToColor(string t)
        {
            int r = HexadecimalToInt32(t.Substring(1, 2));
            int g = HexadecimalToInt32(t.Substring(3, 2));
            int b = HexadecimalToInt32(t.Substring(5, 2));
            return Color.FromArgb(r, g, b);
        }
        public static string PointToString(object value)
		{
			Point data = (Point)value;
			return data.X.ToString() + ";" + data.Y.ToString();
		}
		public static object StringToPoint(string text)
		{
			if (String.IsNullOrEmpty(text)) return Point.Empty;
			string[] items = text.Split(';');
			if (items.Length != 2) return Point.Empty;
			int x = StringInt32(items[0]);
			int y = StringInt32(items[1]);
			return new Point(x, y);
		}
		public static string PointFToString(object value)
		{
			PointF data = (PointF)value;
			return data.X.ToString("N", _Nmfi) + ";" + data.Y.ToString("N", _Nmfi);
		}
		public static object StringToPointF(string text)
		{
			if (String.IsNullOrEmpty(text)) return PointF.Empty;
			string[] items = text.Split(';');
			if (items.Length != 2) return PointF.Empty;
			Single x = StringSingle(items[0]);
			Single y = StringSingle(items[1]);
			return new PointF(x, y);
		}
		public static string RectangleToString(object value)
		{
			Rectangle data = (Rectangle)value;
			return data.X.ToString() + ";" + data.Y.ToString() + ";" + data.Width.ToString() + ";" + data.Height.ToString();
		}
		public static object StringToRectangle(string text)
		{
			if (String.IsNullOrEmpty(text)) return Rectangle.Empty;
			string[] items = text.Split(';');
			if (items.Length != 4) return Rectangle.Empty;
			int x = StringInt32(items[0]);
			int y = StringInt32(items[1]);
			int w = StringInt32(items[2]);
			int h = StringInt32(items[3]);
			return new Rectangle(x, y, w, h);
		}
		public static string RectangleFToString(object value)
		{
			RectangleF data = (RectangleF)value;
            return data.X.ToString("N", _Nmfi) + ";" + data.Y.ToString("N", _Nmfi) + ";" + data.Width.ToString("N", _Nmfi) + ";" + data.Height.ToString("N", _Nmfi);
		}
		public static object StringToRectangleF(string text)
		{
			if (String.IsNullOrEmpty(text)) return RectangleF.Empty;
			string[] items = text.Split(';');
			if (items.Length != 4) return RectangleF.Empty;
			Single x = StringSingle(items[0]);
			Single y = StringSingle(items[1]);
			Single w = StringSingle(items[2]);
			Single h = StringSingle(items[3]);
			return new RectangleF(x, y, w, h);
		}
		public static string SizeToString(object value)
		{
			Size data = (Size)value;
            return data.Width.ToString() + ";" + data.Height.ToString();
		}
		public static object StringToSize(string text)
		{
			if (String.IsNullOrEmpty(text)) return Size.Empty;
			string[] items = text.Split(';');
			if (items.Length != 2) return Size.Empty;
			int w = StringInt32(items[0]);
			int h = StringInt32(items[1]);
			return new Size(w, h);
		}
		public static string SizeFToString(object value)
		{
			SizeF data = (SizeF)value;
            return data.Width.ToString("N", _Nmfi) + ";" + data.Height.ToString("N", _Nmfi);
		}
		public static object StringToSizeF(string text)
		{
			if (String.IsNullOrEmpty(text)) return SizeF.Empty;
			string[] items = text.Split(';');
			if (items.Length != 2) return SizeF.Empty;
			Single w = StringSingle(items[0]);
			Single h = StringSingle(items[1]);
			return new SizeF(w, h);
		}
        public static string FontStyleToString(object value)
        {
            FontStyle fontStyle = (FontStyle)value;
            bool b = ((fontStyle & FontStyle.Bold) != 0);
            bool i = ((fontStyle & FontStyle.Italic) != 0);
            bool s = ((fontStyle & FontStyle.Strikeout) != 0);
            bool u = ((fontStyle & FontStyle.Underline) != 0);
            string result = (b ? "B" : "") + (i ? "I" : "") + (s ? "S" : "") + (u ? "U" : "");
            if (result.Length > 0) return result;
            return "R";
        }
        public static object StringToFontStyle(string text)
        {
            if (String.IsNullOrEmpty(text)) return FontStyle.Regular;
            FontStyle result = (text.Contains("B") ? FontStyle.Bold : FontStyle.Regular) |
                               (text.Contains("I") ? FontStyle.Italic : FontStyle.Regular) |
                               (text.Contains("S") ? FontStyle.Strikeout : FontStyle.Regular) |
                               (text.Contains("U") ? FontStyle.Underline : FontStyle.Regular);
            return result;
        }
        public static string FontToString(object value)
        {
            if (value == null) return "";
            Font font = (Font)value;
            return font.Name + ";" + SingleToString(font.SizeInPoints) + ";" + FontStyleToString(font.Style) + ";" + ByteToString(font.GdiCharSet);
        }
        public static object StringToFont(string text)
        {
            if (String.IsNullOrEmpty(text)) return null;
            string[] items = text.Split(';');
            if (items.Length != 4) return null;
            float emSize = (float)StringToSingle(items[1]);
            FontStyle fontStyle = (FontStyle)StringToFontStyle(items[2]);
            byte gdiCharSet = (byte )StringToByte(items[3]);
            Font result = new Font(items[0], emSize, fontStyle, GraphicsUnit.Point, gdiCharSet);
            return result;
        }
        #endregion
        #region User types
        public static string TimeRangeToString(object value)
        {
            if (!(value is TimeRange))
                return "";
            TimeRange data = (TimeRange)value;
            return DateTimeToString(data.Begin) + "÷" + DateTimeToString(data.End);
        }
        public static object StringToTimeRange(string text)
        {
            if (String.IsNullOrEmpty(text)) return TimeRange.Empty;
            string[] items = text.Split('÷');
            if (items.Length != 2) return TimeRange.Empty;
            DateTime begin = (DateTime)StringToDateTime(items[0]);
            DateTime end = (DateTime)StringToDateTime(items[1]);
            return new TimeRange(begin, end);
        }
        #endregion
		#region Enum types
		/// <summary>
		/// Vrátí název dané hodnoty enum
		/// </summary>
		/// <typeparam name="T"></typeparam>
		/// <param name="value"></param>
		/// <returns></returns>
		public static string EnumToString<T>(T value)
		{
			return Enum.GetName(typeof(T), value);
		}
		/// <summary>
		/// Vrátí hodnotu enumu daného typu z daného stringu
		/// </summary>
		/// <typeparam name="T"></typeparam>
		/// <param name="text"></param>
		/// <returns></returns>
		public static T StringToEnum<T>(string text) where T : struct
		{
			T value;
			if (Enum.TryParse<T>(text, out value))
				return value;
			return default (T);
		}
		/// <summary>
		/// Vrátí hodnotu enumu daného typu z daného stringu
		/// </summary>
		/// <typeparam name="T"></typeparam>
		/// <param name="text"></param>
		/// <param name="defaultValue">Defaultní hodnota</param>
		/// <returns></returns>
		public static T StringToEnum<T>(string text, T defaultValue) where T : struct
		{
			T value;
			if (Enum.TryParse<T>(text, out value))
				return value;
			return defaultValue;
		}
		#endregion
        #region Helpers
        public static Int32 StringInt32(string text)
        {
            if (String.IsNullOrEmpty(text)) return (Int32)0;
            Int32 value;
            if (!Int32.TryParse(text, System.Globalization.NumberStyles.Any, _Nmfi, out value)) return (Int32)0;
            return value;
        }
        public static Single StringSingle(string text)
        {
            if (String.IsNullOrEmpty(text)) return (Single)0;
            Single value;
            if (!Single.TryParse(text, System.Globalization.NumberStyles.Any, _Nmfi, out value)) return (Single)0;
            return value;
        }
        /// <summary>
        /// Vrátí Int32 ekvivalent daného hexadecimálního čísla.
        /// Hexadecimální číslo nesmí obsahovat prefix ani mezery, pouze hexadecimální znaky ("0123456789abcdefABCDEF").
        /// Délka textu je relativně libovolná (v rozsahu Int32, jinak dojde k přetečení).
        /// </summary>
        /// <param name="hexa"></param>
        /// <returns></returns>
        public static Int32 HexadecimalToInt32(string hexa)
        {
            Int64 value = HexadecimalToInt64(hexa);
            if (value > (Int64)(Int32.MaxValue) || value < (Int64)(Int32.MinValue))
                throw new OverflowException("Hexadecimal value " + hexa + " exceeding range for Int32 number.");
            return (Int32)value;
        }
        /// <summary>
        /// Vrátí Int64 ekvivalent daného hexadecimálního čísla.
        /// Hexadecimální číslo nesmí obsahovat prefix ani mezery, pouze hexadecimální znaky ("0123456789abcdefABCDEF").
        /// Délka textu je relativně libovolná (v rozsahu Int64, jinak dojde k přetečení).
        /// </summary>
        /// <param name="hexa"></param>
        /// <returns></returns>
        public static Int64 HexadecimalToInt64(string hexa)
        {
            int result = 0;
            if (hexa == null || hexa.Length == 0 || !ContainOnlyHexadecimals(hexa)) return result;
            int len = hexa.Length;
            int cfc = 1;
            for (int u = (len - 1); u >= 0; u--)
            {
                char c = hexa[u];
                switch (c)
                {
                    case '0':
                        break;
                    case '1':
                        result += cfc;
                        break;
                    case '2':
                        result += 2 * cfc;
                        break;
                    case '3':
                        result += 3 * cfc;
                        break;
                    case '4':
                        result += 4 * cfc;
                        break;
                    case '5':
                        result += 5 * cfc;
                        break;
                    case '6':
                        result += 6 * cfc;
                        break;
                    case '7':
                        result += 7 * cfc;
                        break;
                    case '8':
                        result += 8 * cfc;
                        break;
                    case '9':
                        result += 9 * cfc;
                        break;
                    case 'a':
                    case 'A':
                        result += 10* cfc;
                        break;
                    case 'b':
                    case 'B':
                        result += 11 * cfc;
                        break;
                    case 'c':
                    case 'C':
                        result += 12 * cfc;
                        break;
                    case 'd':
                    case 'D':
                        result += 13 * cfc;
                        break;
                    case 'e':
                    case 'E':
                        result += 14 * cfc;
                        break;
                    case 'f':
                    case 'F':
                        result += 15 * cfc;
                        break;
                }
                cfc = cfc * 16;
            }
            return result;
        }
        /// <summary>
        /// Vrací true, když text obsahuje pouze hexadecimální znaky
        /// </summary>
        /// <param name="text"></param>
        /// <returns></returns>
        public static bool ContainOnlyHexadecimals(string text)
        {
            return ContainOnlyChars(text, "0123456789abcdefABCDEF");
        }
        /// <summary>
        /// Vrací true, když text obsahuje pouze povolené znaky ze seznamu (chars)
        /// </summary>
        /// <param name="text"></param>
        /// <param name="chars"></param>
        /// <returns></returns>
        public static bool ContainOnlyChars(string text, string chars)
        {
            if (text == null) return false;
            foreach (char c in text)
            {
                // Pokud písmeno c (ze vstupního textu) není obsaženo v seznamu povolených písmen, pak vrátíme false (text obsahuje jiné znaky než dané):
                if (!chars.Contains(c)) return false;
            }
            return true;
        }
		/// <summary>
		/// Z daného řetězce (text) odkrojí a vrátí část, která se nachází před delimiterem.
		/// Dany text (ref) zkrátí, bude obsahovat část za delimiterem.
		/// </summary>
		/// <param name="text"></param>
		/// <param name="delimiter"></param>
		/// <returns></returns>
		public static string StringCutOff(ref string text, string delimiter)
		{
			if (text == null) return null;
			if (text.Length == 0) return "";
			string result;
			if (String.IsNullOrEmpty(delimiter))
				throw new ArgumentNullException("delimiter", "Parametr metody Convertor.StringCutOff(«delimiter») nemůže být prázdný.");
			int len = delimiter.Length;
			int at = text.IndexOf(delimiter);
			if (at < 0)
			{
				result = text;
				text = "";
			}
			else if (at == 0)
			{
				result = "";
				text = (at + len >= text.Length ? "" : text.Substring(at + len));
			}
			else
			{
				result = text.Substring(0, at);
				text = (at + len >= text.Length ? "" : text.Substring(at + len));
			}
			return result;
		}
		#endregion
        #endregion
		#region Static konstruktor
		static Convertor()
		{ _PrepareFormats(); }
		#endregion
		#region FormatInfo
		static void _PrepareFormats()
		{
			_Dtfi = new System.Globalization.DateTimeFormatInfo();
            _Dtfi.LongDatePattern = "yyyy-MM-dd HH:mm";                   // Pattern pro formátování písmenem D, musí být nastaveno před nastavením patternu FullDateTimePattern
            _Dtfi.FullDateTimePattern = "yyyy-MM-dd HH:mm:ss.fff";        // Pattern pro formátování písmenem F
			
			_Nmfi = new System.Globalization.NumberFormatInfo();
            _Nmfi.NumberDecimalDigits = 4;
			_Nmfi.NumberDecimalSeparator = ".";
			_Nmfi.NumberGroupSeparator = "";
		}
		static System.Globalization.DateTimeFormatInfo _Dtfi;
		static System.Globalization.NumberFormatInfo _Nmfi;
		#endregion
	}
}
